/*
 * 读绘本导读
 */
import * as React from 'react';
import { connect } from 'react-redux';
import { get, includes } from 'lodash';

import LoadableComponent from 'components/common/LoadableComponent';
const LoadableSentenceEdit = LoadableComponent(() => import('components/common/EditSentence'));
const LoadableAudioPlayer = LoadableComponent(() => import('components/common/AudioPlayer'));
const LoadableDragger = LoadableComponent(() => import('components/common/Dragger'));
const LoadableMedia = LoadableComponent(() => import('components/common/Media'));

import { fetchBookGuide, saveBookGuide } from 'actions/page';

import { Card, Popconfirm, Tooltip, Spin, Icon, Button, message } from 'antd';

const medias = [
  { label: 'image', icon: 'picture', accept: 'image' },
  { label: 'audio', icon: 'notification', accept: 'audio' },
  { label: 'video', icon: 'video-camera', accept: 'video' },
];

interface EditProps {
  dispatch: (action: any) => any;
  loadingGroup: boolean;
  form: any;
  lessonId: number;
  courseId: number;
}
interface EditState {
  editSentence: any;
  editSentenceIndex: number;
  editGuide: any;
}

class EditGuide extends React.Component<EditProps, EditState> {
  static defaultProps: EditProps = {
    dispatch: () => {},
    form: {},
    lessonId: 0,
    courseId: 0,
    loadingGroup: false,
  };

  constructor(props: EditProps) {
    super(props);
    this.state = {
      editSentence: null,
      editSentenceIndex: 0,
      editGuide: {
        attachment: null,
        sentences: [],
      },
    };
  }

  componentDidMount() {
    if (this.props.lessonId) {
      this.handleFetchBookGuide();
    }
  }

  componentWillReceiveProps(nextProps: any) {
    const { lessonId } = nextProps;
    const { lessonId: oldLessonId } = this.props;

    if (lessonId !== oldLessonId) {
      this.handleFetchBookGuide(lessonId);
    }
  }

  handleFetchBookGuide = (lessonId: number = this.props.lessonId) => {
    const { dispatch } = this.props;

    dispatch(fetchBookGuide(lessonId)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        this.setState({
          editGuide: result.response.data,
        });
      }
    });
  };

  onCloseEditor = () => {
    this.setState({
      editSentence: null,
    });
  };

  onOpenEditor = (editSentence: any = 0, editSentenceIndex: number = -1) => {
    this.setState({
      editSentence,
      editSentenceIndex,
    });
  };

  handleSaveBookGuide = (params: Record<string, any>, callback = () => {}) => {
    const { lessonId, dispatch } = this.props;

    dispatch(saveBookGuide(lessonId, params)).then((result: any) => {
      if (result.code) {
        message.error(result.msg);
      } else {
        message.success('保存成功');
        this.handleFetchBookGuide();
        callback();
      }
    });
  };

  handleRemoveMedia = () => {
    const attachmentId = 0;
    this.handleSaveBookGuide({ attachmentId });
  };

  handleRemoveVideoCover = () => {
    const coverImageId = 0;
    this.handleSaveBookGuide({ coverImageId });
  };

  handleUploadDone = (file: any, attachmentType: string) => {
    let data: any = {
      attachmentId: file.id,
    };
    if (attachmentType === 'video') {
      data.coverImageId = 0;
    }

    this.handleSaveBookGuide(data);
  };

  handleUploadCoverDone = (file: any) => {
    const { id: coverImageId } = file;

    this.handleSaveBookGuide({ coverImageId });
  };

  handleRemoveSentence(sentenceIndex: number) {
    const { sentences } = this.state.editGuide;
    sentences.splice(sentenceIndex, 1);

    this.handleSaveBookGuide({ sentences });
  }

  handleSaveSentence = (data: Record<string, any>) => {
    const { audio, sentence } = data;
    const { editSentence, editSentenceIndex, editGuide } = this.state;
    let { sentences } = editGuide;
    const audioId = get(audio, 'id', 0);

    let item: any = {
      sentence,
    };
    if (audioId) {
      item = { ...item, audioId };
    }

    // 请求只需要audioId
    sentences = sentences.map((item: any) => {
      const { audio, ...other } = item;
      if (!audio) {
        return item;
      }

      const audioId = audio.id;
      return { ...other, audioId };
    });

    if (editSentence === 0) {
      // new sentence
      sentences.push(item);
    } else {
      // edit sentence
      sentences[editSentenceIndex] = item;
    }
    this.handleSaveBookGuide({ sentences }, () => {
      this.onCloseEditor();
    });
  };

  renderAttachmentUploader() {
    const { editGuide } = this.state;
    if (editGuide && editGuide.attachment) {
      return null;
    }

    const disabledMedias = ['audio'];
    const filteredMedias = medias.filter((media: any) => {
      return (
        disabledMedias.findIndex(item => {
          return item !== media.label;
        }) !== -1
      );
    });

    const mediaButtons = filteredMedias.map((media: any) => {
      return (
        <LoadableDragger
          key={media.label}
          selectMax={1}
          accept={media.accept}
          onDone={(response: any) => {
            this.handleUploadDone(response.files[0], media.label);
          }}>
          <Button type="primary">
            <Icon type={media.icon} />
          </Button>
        </LoadableDragger>
      );
    });

    if (mediaButtons.length === 0) {
      return null;
    }

    return <div className="test-attachment-upload">{mediaButtons}</div>;
  }

  renderTitle() {
    return (
      <div>
        <h4 className="text-left test-parser-sub-title">上传(视频|动画|图片)</h4>
        {this.renderAttachmentUploader()}
      </div>
    );
  }

  renderMedia() {
    const attachment = get(this.state, 'editGuide.attachment', null);

    return (
      <LoadableMedia
        attachment={attachment}
        onDestroy={this.handleRemoveMedia}
        imageStyle={{ width: '50%' }}
      />
    );
  }

  // 上传视频封面
  renderImageUploader() {
    const { editGuide } = this.state;
    if (editGuide && editGuide.cover) {
      return null;
    }

    return (
      <div className="test-attachment-upload">
        <LoadableDragger
          accept="image"
          selectMax={1}
          onDone={(response: any) => {
            this.handleUploadCoverDone(response.files[0]);
          }}>
          <Button type="primary">
            <Icon type="picture" />
          </Button>
        </LoadableDragger>
      </div>
    );
  }

  renderCoverTitle() {
    return (
      <div>
        <h4 className="text-left test-parser-sub-title">上传(视频封面)</h4>
        {this.renderImageUploader()}
      </div>
    );
  }

  renderVideoCover() {
    const cover = get(this.state, 'editGuide.cover', null);

    return (
      <LoadableMedia
        attachment={cover}
        onDestroy={this.handleRemoveVideoCover}
        imageStyle={{ width: 480 }}
      />
    );
  }

  ConfirmToDelete(props: any) {
    return (
      <Popconfirm
        okText="确定"
        cancelText="取消"
        title="你确定要删除此脚本吗？"
        onConfirm={props.onRemove}>
        <Icon type="close" />
      </Popconfirm>
    );
  }

  renderSentenceList() {
    const sentences = get(this.state.editGuide, 'sentences', []);

    if (sentences.length === 0) {
      return (
        <p className="loadingGroup-placeholder">
          <Icon type="frown-o" />&nbsp;还没有数据，&nbsp;
          <a
            href="javascript:void(0);"
            onClick={() => {
              this.onOpenEditor();
            }}>
            <Icon type="plus" />添加
          </a>
        </p>
      );
    }

    return (
      <div>
        {sentences.map((item: any, index: number) => {
          // 多行的换行显示
          const desc = item.sentence.replace(/\n/g, '<br />');
          const descHtml = <div dangerouslySetInnerHTML={{ __html: desc }} />;
          const audio = get(item, 'audio', null);

          const actions = [
            <Icon
              key={index}
              type="edit"
              onClick={e => {
                e.stopPropagation();
                this.onOpenEditor(item, index);
              }}
            />,
            <this.ConfirmToDelete
              key={index}
              onRemove={this.handleRemoveSentence.bind(this, index)}
            />,
          ];
          return (
            <Card key={index} style={{ width: '100%', marginBottom: 12 }} actions={actions}>
              <Card.Meta
                avatar={audio && <LoadableAudioPlayer isTiny={true} audioUri={audio.uri} />}
                description={descHtml}
                style={{ display: 'flex', alignItems: 'center' }}
              />
            </Card>
          );
        })}
      </div>
    );
  }

  renderSentence() {
    const { editSentence, editGuide } = this.state;
    const attachExt = get(editGuide, 'attachment.ext', '');

    return (
      <div>
        <h4 className="text-left test-parser-sub-title">
          讲解脚本&nbsp;&nbsp;
          <Tooltip key="add sentence" title="添加讲解">
            <Button
              shape="circle"
              type="primary"
              icon="plus"
              onClick={() => {
                this.onOpenEditor();
              }}
            />
          </Tooltip>
        </h4>
        {editSentence !== null && (
          <LoadableSentenceEdit
            needAudio={!includes(['mp4'], attachExt)}
            editSentence={editSentence}
            onCancel={this.onCloseEditor}
            onOk={this.handleSaveSentence}
          />
        )}
        {this.renderSentenceList()}
      </div>
    );
  }

  render() {
    const attachExt = get(this.state.editGuide, 'attachment.ext', '');

    return (
      <div className="test-parser-option-item text-left">
        <Spin spinning={false}>
          <div className="text-center">
            {this.renderTitle()}
            {this.renderMedia()}

            {/* 视频上传还需上传其封面图片 */}
            {includes(['mp4'], attachExt) && (
              <React.Fragment>
                {this.renderCoverTitle()}
                {this.renderVideoCover()}
              </React.Fragment>
            )}

            {this.renderSentence()}
          </div>
        </Spin>
      </div>
    );
  }
}

interface OwnProps {
  lessonId: number;
  courseId: number;
}

function mapStateToProps(state: any, ownProps: OwnProps) {
  const { lessonId, courseId } = ownProps;
  const { loadingGroup } = state;

  return {
    loadingGroup,
    lessonId,
    courseId,
  };
}

export default connect(mapStateToProps)(EditGuide);
